package com.croqodile {
    import flash.display.MovieClip;
    import flash.system.Security;
    import com.senocular.utils.Output;
    import flash.utils.Timer;
    import flash.events.*;
    import com.croqodile.*;
    import com.croqodile.events.*;
    
    public class Controller extends EventDispatcher {
	
	protected static const DEFAULT_ROUTER_HOST:String = "localhost";
	protected static const DEFAULT_ROUTER_PORT:int = 5000;
	
	protected static const POLICY_SERVER_HOST:String = "localhost";
	protected static const POLICY_SERVER_PORT:int = 5001;
	
	protected var _routerCon:RouterMessageConnection;
	protected var _island:IslandReplica;
	protected var _userId:String;
	protected var _msgBuffer:Array = [];

	
	public static function create(islandClass:Class, ...args):Controller{
	    Security.loadPolicyFile("xmlsocket://" + POLICY_SERVER_HOST + ":" + POLICY_SERVER_PORT);
	    var newCont:Controller = new Controller();
	    newCont._userId = newCont.genUserId();
	    newCont._island = islandClass.create.apply(islandClass, args);
	    newCont._island.setController(newCont);
	    
	    //Note! Messages will begin flowing immediately!
	    newCont._routerCon = RouterMessageConnection.create(newCont._userId,
								DEFAULT_ROUTER_HOST,
								DEFAULT_ROUTER_PORT);
	    newCont._routerCon.addEventListener(RouterConnection.CONNECTION_READY,
						newCont.onRouterConnectionReady);
	    newCont._routerCon.addEventListener(RouterConnection.CONNECTION_CLOSED,
						newCont.onRouterConnectionClosed);
	    newCont._routerCon.addEventListener(ExternalMessageEvent.type,
						newCont.onMessageFromRouter);
	    
	    return newCont;
	}
	
	
	protected function genUserId():String {
	    return "user" + (new Date()).getTime() + "avatar" + Math.random();
	}
	
	public function userId():String{
	    return this._userId;
	}
	
	public function island():IslandReplica {
	    return this._island;
	}
	
	public function signalIslandEvent(event:Event):void{
	    this.dispatchEvent(event);
	}
	
	public function propagateFarSend(msgString:String):void{
	    this._routerCon.sendSentence(msgString);
	}
	
	public function disconnectFromRouter():void{
	    this._routerCon.disconnect();
	}
	
	///////////////////////////
        //    Event Handlers	 //
        ///////////////////////////
	
	protected function onRouterConnectionReady(event:Event):void {
	    this.dispatchEvent(new RouterConnectionReadyEvent());
	}
	
	protected function onRouterConnectionClosed(event:Event):void {
	    this.dispatchEvent(new DisconnectedFromRouterEvent());
	}
	
	protected function onMessageFromRouter(e:ExternalMessageEvent):void {
	    this._island.advanceToExternalMessage(ExternalMessage.fromRouterString(e.msg, this._island));
	}
	
    }
}


